<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
  <style>
      #canvas {
          background: #f1f1f1;
      }
  </style>
</head>
<body>
<canvas id="canvas" width="300" height="227"></canvas>
<form>
  <input type="radio" id="original" name="color" value="original" checked="">
  <label for="original">Original</label>

  <input type="radio" id="grayscale" name="color" value="grayscale">
  <label for="grayscale">Grayscale</label>

  <input type="radio" id="inverted" name="color" value="inverted">
  <label for="inverted">Inverted</label>

  <input type="radio" id="sepia" name="color" value="sepia">
  <label for="sepia">Sepia</label>
</form>
<script>
    var img = new Image();
    img.crossOrigin = 'anonymous';
    img.src = 'https://mdn.github.io/dom-examples/canvas/pixel-manipulation/assets/rhino.jpg';

    var canvas = document.getElementById('canvas');
    var ctx = canvas.getContext('2d');

    img.onload = function () {
        ctx.drawImage(img, 0, 0);
    };

    var original = function () {
        ctx.drawImage(img, 0, 0);
    };

    // 图片灰度和反相颜色
    // 在这个例子里，我们遍历所有像素以改变他们的数值。然后我们将被修改的像素数组通过putImageData()放回到画布中去。
    // invert函数仅仅是去减掉颜色的最大色值255
    // grayscale函数仅仅是用红绿和蓝的平均值。你也可以用加权平均
    var invert = function () {
        ctx.drawImage(img, 0, 0);
        const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
        const data = imageData.data;
        for (var i = 0; i < data.length; i += 4) {
            data[i] = 255 - data[i];     // red
            data[i + 1] = 255 - data[i + 1]; // green
            data[i + 2] = 255 - data[i + 2]; // blue
        }
        ctx.putImageData(imageData, 0, 0);
    };

    var grayscale = function () {
        ctx.drawImage(img, 0, 0);
        const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
        const data = imageData.data;
        for (var i = 0; i < data.length; i += 4) {
            var avg = (data[i] + data[i + 1] + data[i + 2]) / 3;
            data[i] = avg; // red
            data[i + 1] = avg; // green
            data[i + 2] = avg; // blue
        }
        ctx.putImageData(imageData, 0, 0);
    };

    const inputs = document.querySelectorAll('[name=color]');
    for (const input of inputs) {
        input.addEventListener("change", function (evt) {
            switch (evt.target.value) {
                case "inverted":
                    return invert();
                case "grayscale":
                    return grayscale();
                default:
                    return original();
            }
        });
    }
</script>


</body>
</html>
